package com.srmt.document.feishu.internal.table.impl;

import com.lark.oapi.service.docx.v1.model.*;
import com.srmt.document.exception.TableException;
import com.srmt.document.feishu.internal.core.BlockUtils;
import com.srmt.document.feishu.internal.table.impl.normal.NormalTableReadOps;
import com.srmt.document.feishu.internal.table.impl.normal.NormalTableWriteOps;
import com.srmt.document.feishu.internal.table.impl.normal.NormalTableStructureOps;
import com.srmt.document.feishu.internal.table.model.TableContext;
import com.srmt.document.feishu.internal.table.model.TableType;
import com.srmt.document.model.ColumnData;
import com.srmt.document.model.RowData;
import com.srmt.document.model.TableData;
import com.srmt.feishu.client.FeishuClient;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * 普通表格操作策略实现 (blockType = 31)
 *
 * 实现标准的飞书表格操作，包含Table -> TableCell -> Text的层次结构。
 *
 * <p><b>架构设计：</b>此类作为协调者（Coordinator），将具体操作委托给专门的操作类：
 * <ul>
 *   <li>{@link NormalTableReadOps} - 处理所有读取操作</li>
 *   <li>{@link NormalTableWriteOps} - 处理所有写入操作</li>
 *   <li>{@link NormalTableStructureOps} - 处理结构修改操作</li>
 * </ul>
 *
 * @author srmt
 * @since 3.0.0
 */
public class NormalTableStrategy extends AbstractTableStrategy {

    private static final Logger logger = LoggerFactory.getLogger(NormalTableStrategy.class);

    // 操作类委托
    private final NormalTableReadOps readOps;
    private final NormalTableWriteOps writeOps;
    private final NormalTableStructureOps structureOps;

    public NormalTableStrategy(FeishuClient client) {
        super(client, TableType.NORMAL_TABLE);

        // 初始化操作类
        this.readOps = new NormalTableReadOps(client);
        this.writeOps = new NormalTableWriteOps(client, readOps);
        this.structureOps = new NormalTableStructureOps(client);

        logger.debug("普通表格策略已使用委托操作初始化");
    }

    // ========== 表格创建 ==========

    @Override
    public Block[] createTableStructure(int rows, int cols, List<List<String>> content)
            throws TableException {
        // 验证输入参数
        validateTableDimensions(rows, cols);

        logger.debug("创建 normal table structure with {} rows and {} columns", rows, cols);

        List<Block> blocks = new ArrayList<>();

        // 生成唯一的Block ID
        String tableId = generateBlockId("table");
        List<String> cellIds = new ArrayList<>();

        // 创建所有单元格ID
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                cellIds.add(generateBlockId("cell_" + i + "_" + j));
            }
        }

        // 创建Table Block
        Table table = Table.newBuilder()
                .property(TableProperty.newBuilder()
                        .rowSize(rows)
                        .columnSize(cols)
                        .columnWidth(generateEqualWidth(cols))
                        .build())
                .build();

        Block tableBlock = Block.newBuilder()
                .blockId(tableId)
                .blockType(BlockUtils.BLOCK_TYPE_TABLE)
                .table(table)
                .children(cellIds.toArray(new String[0]))
                .build();

        blocks.add(tableBlock);

        // 创建所有TableCell Blocks
        int cellIndex = 0;
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                String cellId = cellIds.get(cellIndex);
                String textBlockId = generateBlockId("text_" + i + "_" + j);

                // 获取单元格内容
                String cellContent = "";
                if (content != null && i < content.size() && j < content.get(i).size()) {
                    cellContent = content.get(i).get(j);
                }

                // 创建TableCell Block
                Block cellBlock = Block.newBuilder()
                        .blockId(cellId)
                        .blockType(BlockUtils.BLOCK_TYPE_TABLE_CELL)
                        .tableCell(TableCell.newBuilder().build())
                        .children(new String[]{textBlockId})
                        .build();

                blocks.add(cellBlock);

                // 创建Text Block for cell content
                TextElement[] elements = BlockUtils.createTextElements(cellContent);

                Text text = Text.newBuilder()
                        .elements(elements)
                        .build();

                Block textBlock = Block.newBuilder()
                        .blockId(textBlockId)
                        .blockType(BlockUtils.BLOCK_TYPE_TEXT)
                        .text(text)
                        .children(new String[]{})
                        .build();

                blocks.add(textBlock);
                cellIndex++;
            }
        }

        logger.debug("创建d normal table structure with {} blocks", blocks.size());
        return blocks.toArray(new Block[0]);
    }

    @Override
    public String locateTableCell(TableContext context, int row, int col) throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("普通表格的表格上下文无效");
        }

        logger.debug("在普通表格{}中定位单元格[{}, {}]",
                    row, col, context.getTableBlockId());

        try {
            // 直接使用BlockContext获取单元格Block
            Block cellBlock = context.getBlockContext().getTableCellBlock(
                context.getTableBlockId(), row, col);

            if (cellBlock == null) {
                throw new TableException(
                    String.format("Cell [%d, %d] not found in table", row, col));
            }

            return cellBlock.getBlockId();

        } catch (Exception e) {
            throw new TableException("(locate cell: " + e.getMessage());
        }
    }

    // ========== 读取操作委托 ==========

    @Override
    public String getCellContent(TableContext context, int row, int col) throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("普通表格的表格上下文无效");
        }
        return readOps.getCellContent(context, row, col);
    }

    @Override
    public int[] getTableDimensions(TableContext context) throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("普通表格的表格上下文无效");
        }
        return readOps.getTableDimensions(context);
    }

    @Override
    public TableMergeInfo[] getTableMergeInfo(TableContext context) throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("普通表格的表格上下文无效");
        }
        return readOps.getTableMergeInfo(context);
    }

    @Override
    public boolean isMergedCell(TableContext context, int row, int col) throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("普通表格的表格上下文无效");
        }
        return readOps.isMergedCell(context, row, col);
    }

    @Override
    public TableData convertToTableData(TableContext context) throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("普通表格的表格上下文无效");
        }
        return readOps.convertToTableData(context);
    }

    @Override
    public TableData buildTableFromBlocks(Block tableBlock, Map<String, Block> blockMap)
            throws TableException {
        return readOps.buildTableFromBlocks(tableBlock, blockMap);
    }

    // ========== 写入操作委托 ==========

    @Override
    public void updateCellContentByIndex(TableContext context, int row, int col, String value)
            throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("普通表格的表格上下文无效");
        }

        // 接口定义改为从1开始，内部实现做自减
        row--;
        col--;

        // 定位单元格的Block ID
        String cellBlockId = locateTableCell(context, row, col);
        writeOps.updateCellContentByIndex(context, row, col, value, cellBlockId);
    }

    @Override
    public void batchUpdateCellsByIndex(TableContext context, Map<int[], String> cellUpdates)
            throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("普通表格的表格上下文无效");
        }

        // 创建单元格定位器lambda
        java.util.function.BiFunction<TableContext, int[], String> cellLocator = (ctx, position) -> {
            int row = position[0] - 1;  // 接口定义从1开始
            int col = position[1] - 1;
            try {
                return locateTableCell(ctx, row, col);
            } catch (TableException e) {
                throw new RuntimeException(e);
            }
        };

        writeOps.batchUpdateCellsByIndex(context, cellUpdates, cellLocator);
    }

    @Override
    public void addTableRows(TableContext context, List<RowData> rows, int position)
            throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("普通表格的表格上下文无效");
        }

        // 创建单元格定位器lambda
        java.util.function.BiFunction<TableContext, int[], String> cellLocator = (ctx, position1) -> {
            int row = position1[0];
            int col = position1[1];
            try {
                return locateTableCell(ctx, row, col);
            } catch (TableException e) {
                throw new RuntimeException(e);
            }
        };

        writeOps.addTableRows(context, rows, position, cellLocator);
    }

    @Override
    public void deleteTableRows(TableContext context, int startRow, int endRow)
            throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("普通表格的表格上下文无效");
        }
        writeOps.deleteTableRows(context, startRow, endRow);
    }

    @Override
    public void addTableColumns(TableContext context, List<ColumnData> columns, int position)
            throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("普通表格的表格上下文无效");
        }

        // 创建单元格定位器lambda
        java.util.function.BiFunction<TableContext, int[], String> cellLocator = (ctx, position1) -> {
            int row = position1[0];
            int col = position1[1];
            try {
                return locateTableCell(ctx, row, col);
            } catch (TableException e) {
                throw new RuntimeException(e);
            }
        };

        writeOps.addTableColumns(context, columns, position, cellLocator);
    }

    @Override
    public void deleteTableColumns(TableContext context, int startCol, int endCol)
            throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("普通表格的表格上下文无效");
        }
        writeOps.deleteTableColumns(context, startCol, endCol);
    }

    // ========== 结构操作委托 ==========

    @Override
    public void mergeCells(TableContext context, int startRow, int startCol,
                          int endRow, int endCol) throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("普通表格的表格上下文无效");
        }
        structureOps.mergeCells(context, startRow, startCol, endRow, endCol);
    }

    @Override
    public void unmergeCells(TableContext context, int startRow, int startCol,
                            int endRow, int endCol) throws TableException {
        if (!validateTableOperation(context)) {
            throw new TableException("普通表格的表格上下文无效");
        }
        structureOps.unmergeCells(context, startRow, startCol, endRow, endCol);
    }
}
